import java.util.Date;

public abstract class User {
    protected String id;
    protected String username;
    protected String password;
    protected String userType;
    protected Date registerTime;
    protected String phone;
    protected int loginAttempts;
    protected boolean locked;
    private String newType;

    public User(String id, String username, String password, String phone, String userType) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.phone = phone;
        this.userType = userType;
        this.registerTime = new Date();
        this.loginAttempts = 0;
        this.locked = false;
    }

    public abstract boolean login(String password);

    public void changePassword(String oldPassword, String newPassword) {
        if (!validatePassword(newPassword)) {
            throw new IllegalArgumentException("密码必须包含大小写字母、数字和特殊字符，长度≥8");
        }
        if (!this.password.equals(oldPassword)) {
            throw new IllegalArgumentException("原密码错误");
        }
        this.password = newPassword;
    }

    protected boolean validatePassword(String password) {
        if (password.length() < 8) return false;
        boolean hasUpper = password.chars().anyMatch(Character::isUpperCase);
        boolean hasLower = password.chars().anyMatch(Character::isLowerCase);
        boolean hasDigit = password.chars().anyMatch(Character::isDigit);
        boolean hasSpecial = password.chars().anyMatch(c -> "!@#$%^&*()_+-=[]{}|;:,.<>?".indexOf(c) != -1);
        return hasUpper && hasLower && hasDigit && hasSpecial;
    }

    // Getters and Setters
    public String getId() { return id; }
    public String getUsername() { return username; }
    public String getUserType() { return userType; }
    public Date getRegisterTime() { return registerTime; }
    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }
    public boolean isLocked() { return locked; }
    public void setLocked(boolean locked) { this.locked = locked; }
    public int getLoginAttempts() { return loginAttempts; }
    public void setLoginAttempts(int loginAttempts) { this.loginAttempts = loginAttempts; }

    protected String getType() {
        return "";
    }

    protected void setType(String newType) {
        this.newType = newType;
    }
}